//
//  PHPhotoLibrary+CustomPhotoAlbum.m
//  PHAsset_CustomPhotoAlbum
//
//  Created by jiangxk on 16/3/3.
//  Copyright © 2016年 蒋先科. All rights reserved.
//

#import "PHPhotoLibrary+Save.h"
#import "OMTAlbumManager.h"

typedef NS_ENUM(NSUInteger, OMTAssetType) {
    OMTAssetTypeImage = 1,
    OMTAssetTypeImageURL,
    OMTAssetTypeData,
    OMTAssetTypeVideo,
};

@implementation PHPhotoLibrary (Save)

- (PHAssetCollection *)omt_createAlbum:(NSString *)albumName {
    if (!albumName) return nil;
    PHFetchResult<PHAssetCollection *> *collectionResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
    for (PHAssetCollection *collection in collectionResult) {
        if ([collection.localizedTitle isEqualToString:albumName]) {
            return collection;
        }
    }
    
    __block NSString *collectionId = nil;
    NSError *error;
    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
        collectionId = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:albumName].placeholderForCreatedAssetCollection.localIdentifier;
    } error:&error];
    if (!error) {
        return [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[collectionId] options:nil].firstObject;
    } else {
        return nil;
    }
}

- (void)omt_saveImage:(UIImage *)image album:(NSString *)albumName completion:(PHAssetLibraryWriteImageCompletionBlock)completion failure:(PHAssetLibraryAccessFailureBlock)failure
{
    [self omt_saveObject:image type:OMTAssetTypeImage album:albumName completion:^(id callbackObject) {
        if (completion) completion((PHAsset *)callbackObject);
    } failure:^(NSError *error) {
        if (failure) failure(error);
    }];
}

- (void)omt_saveImageWithImageUrl:(NSURL *)imageUrl album:(NSString *)albumName completion:(PHAssetLibraryWriteImageCompletionBlock)completion failure:(PHAssetLibraryAccessFailureBlock)failure
{
    [self omt_saveObject:imageUrl type:OMTAssetTypeImageURL album:albumName completion:^(id callbackObject) {
        if (completion) completion((PHAsset *)callbackObject);
    } failure:^(NSError *error) {
        if (failure) failure(error);
    }];
}

- (void)omt_saveVideoWithUrl:(NSURL *)videoUrl album:(NSString *)albumName completion:(PHAssetLibraryWriteVideoCompletionBlock)completion failure:(PHAssetLibraryAccessFailureBlock)failure {
    [self omt_saveObject:videoUrl type:OMTAssetTypeVideo album:albumName completion:^(id callbackObject) {
        if (completion) completion((NSURL *)callbackObject);
    } failure:^(NSError *error) {
        if (failure) failure(error);
    }];
}

- (void)omt_saveImageData:(NSData *)imageData album:(NSString *)albumName completion:(PHAssetLibraryWriteImageCompletionBlock)completion failure:(PHAssetLibraryAccessFailureBlock)failure
{
    [self omt_saveObject:imageData type:OMTAssetTypeData album:albumName completion:^(id callbackObject) {
        if (completion) completion((PHAsset *)callbackObject);
    } failure:^(NSError *error) {
        if (failure) failure(error);
    }];
}



- (void)omt_saveObject:(id)object type:(OMTAssetType)type album:(NSString *)albumName completion:(void(^)(id callbackObject))completion failure:(void(^)(NSError *error))failure
{
    if ([OMTAlbumManager authorized]) {
        __block NSString *assetId = nil;
        [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
            assetId = [self _localIdentifier:object type:type];
        } completionHandler:^(BOOL success, NSError * _Nullable error) {
            if (error) {
                return;
            }
            PHAssetCollection *collection = [self omt_createAlbum:albumName];
            [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
                PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection];
                PHAsset *asset = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil].firstObject;
                [request addAssets:@[asset]];
            } completionHandler:^(BOOL success, NSError * _Nullable error) {
                if (success) {
                    switch (type) {
                        case OMTAssetTypeImage:
                        case OMTAssetTypeImageURL:
                        case OMTAssetTypeData: {
                            if (completion) {
                                dispatch_async(dispatch_get_main_queue(), ^{
                                    completion([PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil].firstObject);
                                });
                            }
                            break;
                        }
                            
                        default: {
                            [[PHImageManager defaultManager] requestAVAssetForVideo:[PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil].firstObject options:nil resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
                                if (completion) {
                                    dispatch_async(dispatch_get_main_queue(), ^{
                                        completion([(AVURLAsset *)asset URL]);
                                    });
                                }
                            }];
                            break;
                        }
                    }
                } else {
                    if (failure) {
                        dispatch_async(dispatch_get_main_queue(), ^{
                            failure(error);
                        });
                    }
                }
            }];
        }];
    }
}

- (NSString *)_localIdentifier:(id)object type:(OMTAssetType)type {
    switch (type) {
        case OMTAssetTypeImage:
            return [PHAssetChangeRequest creationRequestForAssetFromImage:(UIImage *)object].placeholderForCreatedAsset.localIdentifier;
        case OMTAssetTypeImageURL:
            return [PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL:(NSURL *)object].placeholderForCreatedAsset.localIdentifier;
        case OMTAssetTypeData: {
            UIImage *image = [UIImage imageWithData:(NSData *)object];
            return [PHAssetChangeRequest creationRequestForAssetFromImage:image].placeholderForCreatedAsset.localIdentifier;
        }
        case OMTAssetTypeVideo:
            return [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:(NSURL *)object].placeholderForCreatedAsset.localIdentifier;
    }
}

- (id)_objectWithAssetId:(NSString *)assetId type:(OMTAssetType)type {
    switch (type) {
        case OMTAssetTypeImage:
        case OMTAssetTypeImageURL:
        case OMTAssetTypeData:
            return [PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil].firstObject;
        default: {
            __block NSURL *url = nil;
            [[PHImageManager defaultManager] requestAVAssetForVideo:[PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil].firstObject options:nil resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
                url = [(AVURLAsset *)asset URL];
            }];
            return url;
        }
    }
}

@end

